﻿using System;
using System.Data;
using System.Text;
using System.Threading.Tasks;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.RegularExpressions;
using System.IO;
using Service.Logic;

namespace Service.Core
{
    class DataMgr
    {
        //先实现单个连接对象，之后使用连接池
        MySqlConnection sqlConn;
        //单例模式
        public static DataMgr instance;
        public DataMgr()
        {
            instance = this;
            Connect();
        }

        //连接
        public void Connect()
        { 
            //数据库  这个应该写在配置文件里面
            string connStr = "Database=game;Data Source=127.0.0.1;";
            connStr += "User Id=root;Password=123456m;port=3306";
            sqlConn = new MySqlConnection(connStr);
            try
            {
                sqlConn.Open();
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return;
            }
        }

        //判断安全字符串，防止sql注入
        public bool IsSafeStr(string str)
        {
            return !Regex.IsMatch(str,@"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
        }

        #region 注册 把信息存入user表中
        //判断用户是否存在
        private bool CanRegister(string id)
        { 
            if(!IsSafeStr(id)) return false;

            //查询id是否存在
            string cmdStr = string.Format("select * from user where id='{0}';",id);
            MySqlCommand cmd = new MySqlCommand(cmdStr,sqlConn);

            try
            {
                MySqlDataReader dataReader = cmd.ExecuteReader();//返回查询结果
                bool hasRows = dataReader.HasRows;
                dataReader.Close();
                return !hasRows;//hasRows代表从数据返回有数据，但是返回！hasRows是什么意思
            }catch(Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
        }

        //注册
        public bool Register(string id,string pw)
        { 
            if(!IsSafeStr(id)||!IsSafeStr(pw)) return false;
            //能否注册
            if (!CanRegister(id)) return false;
            //写入数据库User表
            string cmdStr = string.Format("insert into user set id='{0}',pw='{1}';",id,pw);
            MySqlCommand cmd = new MySqlCommand(cmdStr,sqlConn);
            try
            {
                cmd.ExecuteNonQuery();
                return true;
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }
        #endregion

        #region 创建角色 把角色信息序列化后存入player表
        public bool CreatePlayer(string id)
        { 
            if(!IsSafeStr(id)) return false;
            //序列化
            IFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            PlayerData playerDate = new PlayerData();
            try
            {
                //把对象序列化为字节流
                formatter.Serialize(stream,playerDate);  
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }

            //把字节流转化为byte数组
            byte[] byteArr = stream.ToArray();
            //写入数据
            string cmdStr = string.Format("insert into player set id='{0}',data=@data;",id);
            MySqlCommand cmd = new MySqlCommand(cmdStr,sqlConn);
            cmd.Parameters.Add("@data",MySqlDbType.Blob);
            cmd.Parameters[0].Value = byteArr;
            try
            {
                cmd.ExecuteNonQuery();
                return true;
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }
        #endregion

        #region 登录检验
        public bool CheckPassWord(string id,string pw)
        { 
            if(!IsSafeStr(id)||!IsSafeStr(pw)) return false;
            //查询
            string cmdStr = string.Format("select * from user where id='{0}',pw='{1}';",id,pw);
            MySqlCommand cmd = new MySqlCommand(cmdStr,sqlConn);
            try
            {
                MySqlDataReader dataReader = cmd.ExecuteReader();
                bool hasRows = dataReader.HasRows;
                dataReader.Close();
                return hasRows;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
        }
        #endregion

        #region 获取角色信息
        public PlayerData GetPlayerData(string id)
        {
            PlayerData playerData = null;
            if(!IsSafeStr(id)) return playerData;
            //查询
            string cmdStr = string.Format("select * from player where id='{0}';",id);
            MySqlCommand cmd = new MySqlCommand(cmdStr,sqlConn);
            byte[] buffer = new byte[1];//用来存放player表的data字段的数据
            try
            {
                MySqlDataReader dataReader = cmd.ExecuteReader();
                if(!dataReader.HasRows)
                {
                    dataReader.Close();
                    return playerData;
                }
                dataReader.Read();//读下一条数据

                long len = dataReader.GetBytes(1, 0, null, 0, 0);//1代表player表的data字段的数据
                buffer = new byte[len];
                dataReader.GetBytes(1,0,buffer,0,(int)len);
                dataReader.Close();
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return playerData;
            }

            //反序列化
            MemoryStream stream = new MemoryStream(buffer);
            try
            {
                BinaryFormatter formatter = new BinaryFormatter();
                playerData = (PlayerData)formatter.Deserialize(stream);
                return playerData;
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return playerData;
            }
        }
        #endregion

        #region 保存角色信息
        public bool SavePlayer(Player player)
        {
            string id = player.id;
            PlayerData playerData = player.data;
            //序列化
            IFormatter fomatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            try 
            {
                fomatter.Serialize(stream,playerData);
                //return true;
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }

            byte[] byteArr = stream.ToArray();
            //写入数据
            string cmdStr = string.Format("update player set data=@data where id='{0}';",player.id);
            MySqlCommand cmd = new MySqlCommand(cmdStr,sqlConn);
            cmd.Parameters.Add("@data",MySqlDbType.Blob);
            cmd.Parameters[0].Value = byteArr;
            try
            {
                cmd.ExecuteNonQuery();
                return true;
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }
        #endregion
    }
}
